<?php if (!defined('CODELIGHTER')) exit('No direct script access allowed');
/**
 * MySQL Database utilites for CodeLighter
 * 
 * @author xrip <z.xrip.z@gmail.com>
 * @copyright 2009 xrip
 * @package MySQL
 * @require CodeLighter
 * @version 0.1
 */
 
class DBException extends Exception
{
    public function __construct($message, $code = 0)
    {
        $this->message[] = mysql_error();
        $this->message[] = $this->hightlight($message);
    }

    private function hightlight($sql)
	{
		$sql = nl2br($sql);
		
		// Hightlight symbols
		$sql = preg_replace("#(\(|\)|\,|\=|\.|-|\+|\!|\@)#si", "<span style='color: navy'>$1</span>", $sql);

		// Hightlight digits
		$sql = preg_replace("#([0-9]+)#si", "<span style='color: orange'>$1</span>", $sql);
		
		// Hightlight keywords
		$sql = preg_replace("#(SELECT|UPDATE|INSERT|DELETE|DROP|TRUNCATE|FROM|WHERE|IN|AS|JOIN|INNER|LEFT|RIGHT|LIMIT|GROUP BY|ORDER BY|ON|HAVING|COUNT|MIN|MAX)\s#si", "<b style='color: blue'>$1</b>&nbsp;", $sql);
	
		return $sql;
	}
}

class DB {
    
    //connection variables
    protected $dbhost = '127.0.0.1';
    protected $dbuser = 'root';
    protected $dbpass = '';
    protected $dbname = 'mysql';
    
    //normal global resources
    protected $db = null;
    protected static $instance = null;
    
    protected $query = null;

    /**
     * Singleton pattern for instantiating the DB class
     */
    public static function GetInstance()
    {
        if(!self::$instance)
        {
            self::$instance = new DB;
        }
        return self::$instance;
    }
    
    protected function __construct()
    {
        if(($db = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpass)) === false)
        {
            throw new DBException("Can't connect to {$this->dbuser}@{$this->dbhost}");
        }
        
        if((@mysql_select_db($this->dbname, $db)) === false)
        {
            throw new DBException("Can't connect to database {$this->dbname}");
        }
        $this->db = $db;
    }
    
    /**
     * simple method for sanitizing SQL query strings.
     */
    public function Clean($string)
    {
        if(get_magic_quotes_gpc())
        {
            $string = stripslashes($string);
        }
        return mysql_real_escape_string($string);
    }
    
    /**
     * DB class method call to the Query child class.
     * SELECT queries only
     * Returns an object.
     */
    public function Query($statement)
    {
        $this->query = $statement;
        return $query = new Query($statement, $this->db);
    }
    
    /**
     * Used to get the last inserted record
     */
    public function InsertID()
    {
        return mysql_insert_id($this->link);
    }
    
    
    public function __destruct()
    {
        @mysql_close($this->db);
    }
    
}

/**
 * These are separate classes for the reason that I would like
 * to be able to edit them with as little distruption to the 
 * flow of the parent class as possible. 
 */

/**
 * Query child class. Used for running SELECT queries.
 * Called exclusively by the DB parent class in the Query method
 */
class Query
{
    protected $result;
    private $link = null;
    
    public function __construct($query, $link)
    {
        $this->link = $link;
        if(($this->result = mysql_query($query, $link)) === false)
        {
            throw new DBException($query);
        }
    }
    
    public function Result()
    {
        $result = array();
        while ($row = $this->row())
        {
            $result[] = $row;
        }

        return $result;
    }

    public function Result_array()
    {
        $result = array();
        while ($row = @mysql_fetch_assoc($this->result))
        {
            $result[] = $row;
        }

        return $result;
    }


    public function Row($class = null)
    {
        return @mysql_fetch_object($this->result);
    }

    public function num_rows()
    {
        return @mysql_num_rows($this->link);
    }

    
    public function __destruct()
    {
        @mysql_free_result($this->result);
    }
}


?>
